package com.hosever.controller;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Scanner;
import java.util.UUID;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.util.HtmlUtils;
import com.hosever.core.AbstractController;
import com.hosever.model.DemoModel;
import com.hosever.service.DemoService;
import com.hosever.utils.FileUtils;
import com.hosever.utils.SeverStringUtils;

@Controller
@RequestMapping("/pub/tools")
public class ToolController extends
	AbstractController<DemoModel, DemoService>{

	@RequestMapping("/list")
	public String toolList(Model model,HttpSession session) {
		session.setAttribute("nav", "tool");
		return getRelativePath("/formList");
	}
	
	@RequestMapping(value="/view/{toolName}", method = RequestMethod.GET)
	public String toolView(@PathVariable("toolName") String toolName,HttpSession session) {
		String menuItem =  "tool";
		session.setAttribute("nav", menuItem);
		
		return getRelativePath("/"+toolName);
	}
	
	@RequestMapping(value="/view/CodeGeneraterForZsoft", method = RequestMethod.GET)
	public String toolCodeGenerater(HttpSession session) {
		String menuItem =  "tool";
		session.setAttribute("nav", menuItem);
		
		return getRelativePath("/CodeGeneraterForZsoft");
	}
	
	/**
	 * 工具-代码生成器（中智专版）
	 * @param className
	 * @param tableName
	 * @param design
	 * @param model
	 * @return
	 */
	@RequestMapping(value="/view/CodeGeneraterForZsoft",method = RequestMethod.POST)
	public String CodeGeneraterP(@RequestParam("className") String className//类名
			,@RequestParam("tableName") String tableName//表名
			,@RequestParam("design") String design//类设计
			,Model model){
		model.addAttribute("design", design);
		model.addAttribute("className", className);
		model.addAttribute("tableName", tableName);
		className = className.trim().replaceAll(" ", "");//前后删除空格，中间也要
		if(!className.isEmpty()){
			className = SeverStringUtils.toUpperCaseFirstOne(className);
		}
		
		tableName = tableName.trim().replaceAll(" ", "");
		if(StringUtils.isBlank(design)){
			return getRelativePath("/tools/CodeGeneraterForZsoft");
		}
		String[] rows = design.split("\n");
		
		String paramCode="";//java属性
		String methodCode="";//java方法
		
		String uuid = UUID.randomUUID().toString();
//		Calendar calendar = Calendar.getInstance();
		SimpleDateFormat shortSdf = new SimpleDateFormat("yyyyMMdd");
		String shortDate = shortSdf.format(new Date());
		
		//oracle创建脚本
		String oracleCreateCode="/** 脚本执行记录 select sys_guid() from dual **/\n"
				+ "insert into S_SCRIPT_RECORD(ID, NAME,DESCRITION) values \n"
				+ "('"+uuid+"', '【版本号】_1_创建脚本_【数据库名】_"+shortDate+"(【脚本说明】).sql', '');\n"
				+ "commit;\n\n"
				+ "create table "+tableName+"(\n"
				+ "\tid VARCHAR2(50) not null primary key,\n"
				+ "\tcreator_id VARCHAR2(50),\n"
				+ "\tcreation_time DATE not null,\n"
				+ "\tlast_modificator_id VARCHAR2(50),\n"
				+ "\tlast_modification_time DATE not null,\n";
		String oracleCreateItem="";//oracle创建项
		
		
		//oracle说明
		String oracleCreateComment="comment on column "+tableName+".id is '唯一标识';\n"
				+ "comment on column "+tableName+".creator_id is '创建者id';\n"
				+ "comment on column "+tableName+".creation_time is '创建时间';\n"
				+ "comment on column "+tableName+".last_modificator_id is '修改者id';\n"
				+ "comment on column "+tableName+".last_modification_time is '修改时间';\n";
		
		for(String row : rows){
			String[] cols = row.split("\\s+");
			if(cols.length==5){
				String paramName = cols[0];//属性名
				paramName = SeverStringUtils.toLowerCaseFirstOne(paramName);//首字母小写
				String paramType = cols[1];//属性类型，需要判断基本类型外的数据类型都要大写
				String length = cols[2];//长度
				String nullable = cols[3];//可空
				String statement = cols[4];//说明
				if(StringUtils.equals(nullable, "是")
						||StringUtils.equals(nullable, "yes")
						||StringUtils.equals(nullable, "true")
						||StringUtils.equals(nullable, "1")){
					nullable = "true";
				}
				if(StringUtils.equals(nullable, "否")
						||StringUtils.equals(nullable, "no")
						||StringUtils.equals(nullable, "false")
						||StringUtils.equals(nullable, "0")){
					nullable = "false";
				}
				
				paramCode+= 
						  "\t/** \n"
						+ "\t * "+statement+"\n"
						+ "\t */\n"
						+ "\tprivate "+paramType+" "+paramName+";\n";
				
				String dataColumn = "";//数据库字段映射
				if(StringUtils.isNotBlank(tableName)){
					dataColumn = "\t@Column(name = \""+paramName+"\""+(!length.equals("-")?", length = "+length:"")+")\n";
				}
				
				methodCode+="\t/**\n"
						+ "\t * 设置属性 "+statement+"\n"
						+ "\t * @param "+paramName+" "+statement+"\n"
						+ "\t */\n"
						+ "\tpublic void set"+SeverStringUtils.toUpperCaseFirstOne(paramName)+"("+paramType+" "+paramName+") {\n"
						+ "\t\tthis."+paramName+"="+paramName+";\n"
						+ "\t}\n"
						+ "\n"
						+ "\t/**\n"
						+ "\t * 获取属性 "+statement+"\n"
						+ "\t * @return "+statement+"\n"
						+ "\t */\n"
						+ dataColumn
						+ "\tpublic "+paramType+" get"+SeverStringUtils.toUpperCaseFirstOne(paramName)+"() {\n"
						+ "\t\treturn this."+paramName+";\n"
						+ "\t}\n\n";
				
				//oracle数据库脚本
				oracleCreateItem+="\t"+paramName+" "+oracleDataType(paramType, length);
				if(StringUtils.equals(nullable, "false")){
					oracleCreateItem += " not null";
				}
				oracleCreateItem+=",\n";
				
				//oracle说明
				oracleCreateComment+="comment on column "+tableName+"."+paramName+" is '"+statement+"';\n";
			}
		}
		
		String entityAnnotation = "";//@Entity
		String tableAnnotation = "";//@Table
		if(StringUtils.isNotBlank(tableName)){
			entityAnnotation = "@Entity\n";
			tableAnnotation = "@Table(name = \""+tableName+"\")\n";
		}
		
		String domainCode = entityAnnotation
				+ tableAnnotation
				+ "public class "+className+" extends AbstractDomainEntity{\n"
				+ paramCode
				+ "\n"
				+ methodCode
				+ "}";
		domainCode=HtmlUtils.htmlEscape(domainCode);
		model.addAttribute("domainCode", domainCode);
		
		String repositoryCode = "@Repository\n";
		repositoryCode+="public interface "+className+"Repository extends GenericJpaRepository<"+className+", String>{\n"
				+ "\n"
				+ "}";
		
		repositoryCode=HtmlUtils.htmlEscape(repositoryCode);
		model.addAttribute("repositoryCode", repositoryCode);
		
		String serviceCode = "";
		serviceCode+=
				"public interface "+className+"Service extends GenericService<"+className+", "+className+"Repository>{\n"
				+ "\n"
				+ "}";
		
		serviceCode=HtmlUtils.htmlEscape(serviceCode);
		model.addAttribute("serviceCode", serviceCode);
		
		String serviceImplCode = "@Service\n";
		serviceImplCode+=
				"public class "+className+"ServiceImpl extends AbstractGenericService<"+className+", "+className+"Repository> implements "+className+"Service{\n"
				+ "\n"
				+ "}";
		
		serviceImplCode=HtmlUtils.htmlEscape(serviceImplCode);
		model.addAttribute("serviceImplCode", serviceImplCode);
		
		if(!StringUtils.isBlank(tableName)){
			if(!StringUtils.isBlank(oracleCreateItem)){
				oracleCreateItem=oracleCreateItem.substring(0,oracleCreateItem.length()-2);
				oracleCreateCode+=oracleCreateItem;
			}
			oracleCreateCode+="\n);";
			oracleCreateCode+="\n\n"+oracleCreateComment;
			oracleCreateCode=HtmlUtils.htmlEscape(oracleCreateCode);
			model.addAttribute("oracleCreateCode", oracleCreateCode);
		}
		
		
		return getRelativePath("/CodeGeneraterForZsoft");
	}
	
	/**
	 * oracle数据类型
	 * @param javaType
	 * @param length
	 * @return
	 */
	private String oracleDataType(String javaType,String length){
		String dataType="";
		if(StringUtils.equalsIgnoreCase(javaType, "String")){
			dataType="VARCHAR2";
		}else if(StringUtils.equalsIgnoreCase(javaType, "int")
				||StringUtils.equalsIgnoreCase(javaType, "integer")
				||StringUtils.equalsIgnoreCase(javaType, "long")
				||StringUtils.equalsIgnoreCase(javaType, "float")
				||StringUtils.equalsIgnoreCase(javaType, "double")
				||StringUtils.equalsIgnoreCase(javaType, "byte")
				||StringUtils.equalsIgnoreCase(javaType, "short")
				||StringUtils.equalsIgnoreCase(javaType, "BigDecimal")){
			dataType="NUMBER";
		}else{
			dataType = javaType;
		}
		
		if(length!=null && !StringUtils.equals(length, "-")){
			dataType+=("("+length+")");
		}
		return dataType;
	}
	
	
	@RequestMapping(value="/patchMaker",method = RequestMethod.POST)
	public String patchMakerP(
			@RequestParam("projectMainPath") String projectMainPath
			,@RequestParam("targetMainPath") String targetMainPath
			,@RequestParam("systemName") String systemName
			,@RequestParam("patchName") String patchName
			,@RequestParam("fileList") String fileList
			,Model model){
		model.addAttribute("projectMainPath", projectMainPath);
		model.addAttribute("targetMainPath", targetMainPath);
		model.addAttribute("systemName", systemName);
		model.addAttribute("patchName", patchName);
		model.addAttribute("fileList", fileList);
		fileList = fileList.replace("\r", "");
		
		String message = "";
		if(SeverStringUtils.isBlank(projectMainPath)
				||SeverStringUtils.isBlank(projectMainPath)
				||SeverStringUtils.isBlank(targetMainPath)
				||SeverStringUtils.isBlank(systemName)
				||SeverStringUtils.isBlank(fileList)){
			message="生成失败，参数不全！";
			model.addAttribute("message", message);
			return getRelativePath("/patchMaker");
		}
		
		
		// 生成补丁
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String todayString = sdf.format(new Date());
		String systemNamePlus = todayString+systemName;
		String newRoot = targetMainPath + "\\" + systemNamePlus + "\\";

		String[] dirFileList = fileList.split("\n");
		
		
		for (String dirFile : dirFileList) {
			String[] dirFileArray = dirFile.split("\\\\");
			
			String fileName = dirFileArray[dirFileArray.length - 1];
			String dir = dirFile.replace(fileName, "");
			String newDir = dir;
			String projectName = dirFileArray[0];
			if(SeverStringUtils.isNotBlank(patchName)){
				newDir = dir.replace(projectName, patchName);
			}
			
			
			try {
				FileUtils.copyFile(projectMainPath + "\\" + dir, newRoot + newDir, fileName);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		//生成说明文件
		try {
			System.out.println("===生成说明文件===");
			File directory = new File(newRoot);
			String prefix = "【说明】"+systemNamePlus;
			String suffix = ".txt";
//					File file = File.createTempFile(prefix, suffix, directory);
			
			File file =new File(directory, prefix+suffix);
			if(!file.exists()){
				file.createNewFile();
			}
			
			String data = "文件清单：\n";
			for (String dirFile : dirFileList) {
				String projectName = dirFile.split("\\\\")[0];
				String newDirFile = dirFile;
				if(SeverStringUtils.isNotBlank(patchName)){
					newDirFile = dirFile.replace(projectName, patchName);
				}
				data+=newDirFile+"\n";
			}
			data+="\n";
			data+="说明：\n";
			data+="覆盖文件";
			
			FileWriter fileWritter = new FileWriter(file.getAbsoluteFile());
            BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
            bufferWritter.write(data);
            bufferWritter.close();
			
			System.out.println(newRoot+prefix+suffix);
			
		} catch (IOException e) {
			e.printStackTrace();
		} 
		
		message+= "生成成功，输出路径："+targetMainPath+"\n";
		model.addAttribute("message", message);
		return getRelativePath("/patchMaker");
	}
}














